/* Copyright 2009 Anthony Surma
This file is part of Java's Kademlia Extension (JKADX).

JKADX is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.

JKADX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with JKADX.  If not, see <http://www.gnu.org/licenses/>.
 */

package jkadx.dht;

import static org.junit.Assert.assertEquals;
import org.junit.Test;
import java.net.InetAddress;


/**
 *
 * @author Anthony Surma
 */
public class TestContact implements DHTInterface
{
    private final static byte[] IP_ADDRESS1 = { 123, 123, 123, 123 };
    private final static byte[] IP_ADDRESS2 = { 123, 123, 123, 122 };
    private final Contact contact1 = new Contact (UniqueId.newRandom(), IP_ADDRESS1, 1111);
    private final Contact contact2 = new Contact (UniqueId.newRandom(), IP_ADDRESS2, 1333);
    private final Contact contact3 = new Contact (UniqueId.newRandom(), IP_ADDRESS2, 1333);

    
    @Test
    public void testToString() // XXX this isn't really much of a test
    {
	final Contact contact = new Contact(new UniqueId(),
		IP_ADDRESS1, 1234);
	final StringBuilder bits = new StringBuilder(UniqueId.NBITS);
	final String obtainedresult;
	final String expectedresult;

	for (int i = 0; i < UniqueId.NBITS; i++)
	{
	    bits.append("0");
	}	
	obtainedresult = contact.toString();
	expectedresult = bits.toString() + "/123.123.123.123/1234";
	assertEquals("Failed to get proper string value",
		expectedresult, obtainedresult);
    }

 /**
  * @author Desai
  */
    @Test
    public void testmatchesSocketAddress ()
    {
        assertEquals ("Failed to return False when Contacts IPADDRESS and ports dont match", false, contact1.matchesSocketAddress(contact2));

        assertEquals ("Failes to return True when Contacts IPADDRESS and ports do match", true, contact2.matchesSocketAddress(contact3));

    }

 /**
  * @author Desai
  */
    @Test
    public void testEquals ()
    {
        final Contact contact4 = new Contact (UniqueId.newRandom(), IP_ADDRESS1, 1111);
        final Contact contact5 = new Contact (contact4.uniqueId, IP_ADDRESS1, 1111);
        final Contact contact6 = new Contact (UniqueId.newRandom(), IP_ADDRESS1, 2222);

        assertEquals ("Failed to return true when same UniqueId HashCodes", true, contact4.hashCode()==contact5.hashCode());

        assertEquals ("Failed to return false when different UniqueId HashCodes", false, contact4.hashCode()==contact6.hashCode());

        assertEquals ("Failed to return true when same Contacts with same Contact Triples", true, contact4.equals(contact5));
        
        assertEquals ("Failed to return false when unqual hashcode", false, contact6.equals(contact5));

    }
  
    @Test
    public void testMatches() throws Exception
    {
	final UniqueId bitSet1 = new UniqueId("0");
	final UniqueId bitSet2 = new UniqueId("1");
	final UniqueId bitSet4 = new UniqueId("1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
	final UniqueId bitSet5 = new UniqueId("1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
	final Contact contact1 = new Contact(bitSet1, IP_ADDRESS1, 1234);
	final Contact contact2 = new Contact(bitSet2, IP_ADDRESS1, 1234);
	final Contact contact4 = new Contact(bitSet4, IP_ADDRESS2, 1234);
	final Contact contact5 = new Contact(bitSet5, IP_ADDRESS1, 1235);

        assertEquals("New contacts should not be locked.", contact1.isLocked.get(), false);

	System.out.println();
	//System.out.println(contact1);
	assertEquals("Failed to match contacts with identical ports and ip addresses",
		true, contact1.matchesSocketAddress(contact2));

	//System.out.println(contact2);
	assertEquals("Failed to differentiate contacts with different ip addresses",
		false, contact1.matchesSocketAddress(contact4));

	//System.out.println(contact4);
	assertEquals("Failed to differentiate contacts with different ports and ip addresses",
		false, contact4.matchesSocketAddress(contact5));
	
	//System.out.println(contact5);
	assertEquals("Failed to differentiate contacts with different ports",
		false, contact2.matchesSocketAddress(contact5));

        Contact testContact1 = new Contact(UniqueId.newRandom(), IP_ADDRESS1, 62128);
        byte[] byteArray = testContact1.toByteArray();
        Contact testContact2 = new Contact(byteArray);
        
        assertEquals("Failed to properly convert contact to bytestream and back",
		testContact1, testContact2);
        assertEquals("Failed to properly convert contact to bytestream and back",
		testContact1.uniqueId.toString() + testContact1.getInetSocketAddress().getAddress().toString() + "/62128", testContact2.toString());
    }

    public static void main(String[] args)
    {
	org.junit.runner.JUnitCore.main(TestContact.class.getName());
    }

    @Override
    public boolean isConnected(Contact oldest)
    {
	throw new UnsupportedOperationException("Not supported yet.");
    }
}